﻿using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Update;
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal;
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
using Pomelo.EntityFrameworkCore.MySql.Migrations;
using System.Diagnostics.CodeAnalysis;

namespace Common.EfCore;

public class CustomSqliteMigrationsSqlGenerator : SqliteMigrationsSqlGenerator
{
    public CustomSqliteMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies,
        IRelationalAnnotationProvider migrationsAnnotations) : base(dependencies, migrationsAnnotations)
    {
    }

    /// <summary>
    ///     Generates a SQL fragment for the constraints of a <see cref="CreateTableOperation" />.
    /// </summary>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to add the SQL fragment.</param>
    protected override void CreateTableConstraints(
        CreateTableOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
    {
        CreateTablePrimaryKeyConstraint(operation, model, builder);
        CreateTableUniqueConstraints(operation, model, builder);
        CreateTableCheckConstraints(operation, model, builder);
    }
}

public class CustomMySqlMigrationsSqlGenerator : MySqlMigrationsSqlGenerator
{
    public CustomMySqlMigrationsSqlGenerator(
        [NotNullAttribute] MigrationsSqlGeneratorDependencies dependencies, 
        [NotNullAttribute] ICommandBatchPreparer commandBatchPreparer,
        [NotNullAttribute] IMySqlOptions options) 
        : base(dependencies, commandBatchPreparer, options)
    {
    }

    /// <summary>
    ///     Generates a SQL fragment for the constraints of a <see cref="CreateTableOperation" />.
    /// </summary>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to add the SQL fragment.</param>
    protected override void CreateTableConstraints(
        CreateTableOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
    {
        CreateTablePrimaryKeyConstraint(operation, model, builder);
        CreateTableUniqueConstraints(operation, model, builder);
        CreateTableCheckConstraints(operation, model, builder);
    }
}

public class CustomSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
    public CustomSqlServerMigrationsSqlGenerator(
        MigrationsSqlGeneratorDependencies dependencies, 
        ICommandBatchPreparer commandBatchPreparer) 
        : base(dependencies, commandBatchPreparer)
    {
    }

    /// <summary>
    ///     Generates a SQL fragment for the constraints of a <see cref="CreateTableOperation" />.
    /// </summary>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to add the SQL fragment.</param>
    protected override void CreateTableConstraints(
        CreateTableOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
    {
        CreateTablePrimaryKeyConstraint(operation, model, builder);
        CreateTableUniqueConstraints(operation, model, builder);
        CreateTableCheckConstraints(operation, model, builder);
    }
}

public class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
{
    public CustomNpgsqlMigrationsSqlGenerator(
        MigrationsSqlGeneratorDependencies dependencies, 
        INpgsqlSingletonOptions npgsqlSingletonOptions) 
        : base(dependencies, npgsqlSingletonOptions)
    {
    }

    /// <summary>
    ///     Generates a SQL fragment for the constraints of a <see cref="CreateTableOperation" />.
    /// </summary>
    /// <param name="operation">The operation.</param>
    /// <param name="model">The target model which may be <see langword="null" /> if the operations exist without a model.</param>
    /// <param name="builder">The command builder to use to add the SQL fragment.</param>
    protected override void CreateTableConstraints(
        CreateTableOperation operation,
        IModel? model,
        MigrationCommandListBuilder builder)
    {
        CreateTablePrimaryKeyConstraint(operation, model, builder);
        CreateTableUniqueConstraints(operation, model, builder);
        CreateTableCheckConstraints(operation, model, builder);
        CreateTableForeignKeys(operation, model, builder);
    }

    protected override void CreateTableForeignKeys(
    CreateTableOperation operation,
    IModel? model,
    MigrationCommandListBuilder builder)
    {
        
    }
}